﻿using BoriPeter.FatSecret;
using BoriPeter.FitnessJournal8.ViewModels;
using BoriPeter.FitnessJournal8.Views;
using Caliburn.Micro;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Windows.ApplicationModel;
using Windows.ApplicationModel.Activation;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
using System.Reflection;
using BoriPetr.OAuth;
using BoriPeter.FatSecret.Messages;

// The Blank Application template is documented at http://go.microsoft.com/fwlink/?LinkId=234227

namespace BoriPeter.FitnessJournal8
{
    /// <summary>
    /// Provides application-specific behavior to supplement the default Application class.
    /// </summary>
    sealed partial class App : CaliburnApplication
    {
        private AuthenticationManager authentiacationManager;
        private WinRTContainer container;

        #region App()
        /// <summary>
        /// Initializes the singleton application object.  This is the first line of authored code
        /// executed, and as such is the logical equivalent of main() or WinMain().
        /// </summary>
        public App()
        {
            this.InitializeComponent();
            this.Suspending += OnSuspending;
        }
        #endregion

        #region OnLaunched()
        /// <summary>
        /// Invoked when the application is launched normally by the end user.  Other entry points
        /// will be used when the application is launched to open a specific file, to display
        /// search results, and so forth.
        /// </summary>
        /// <param name="args">Details about the launch request and process.</param>
        protected override async void OnLaunched(LaunchActivatedEventArgs args)
        {
            DisplayRootView<RootView>();
        }
        #endregion

        #region OnSuspending()
        /// <summary>
        /// Invoked when application execution is being suspended.  Application state is saved
        /// without knowing whether the application will be terminated or resumed with the contents
        /// of memory still intact.
        /// </summary>
        /// <param name="sender">The source of the suspend request.</param>
        /// <param name="e">Details about the suspend request.</param>
        private async void OnSuspending(object sender, SuspendingEventArgs e)
        {
            var deferral = e.SuspendingOperation.GetDeferral();

            await ViewModelBase.NutritionSource.SaveAllAsync();

            deferral.Complete();
        }
        #endregion

        #region OnSearchActivated()
        protected override void OnSearchActivated(SearchActivatedEventArgs args)
        {
            if (ViewModelBase.NavigationService != null)
            {
                ViewModelBase.NavigationService.UriFor<SearchViewModel>()
                    .WithParam(m => m.SearchExpression, args.QueryText)
                    .Navigate();
            }
            else
            {
                DisplayRootView<SearchView>(args.QueryText);
            }
        }
        #endregion

        #region Configure()
        protected override void Configure()
        {
            container = new WinRTContainer();
            container.RegisterWinRTServices();

            //TODO: Register your view models at the container
        }
        #endregion

        #region IsConcrete()
        private static bool IsConcrete(Type service)
        {
            var serviceInfo = service.GetTypeInfo();
            return !serviceInfo.IsAbstract && !serviceInfo.IsInterface;
        }
        #endregion

        #region GetInstance
        protected override object GetInstance(Type service, string key)
        {
            var obj = container.GetInstance(service, key);

            // mimic previous behaviour of WinRT SimpleContainer
            if (obj == null && IsConcrete(service))
            {
                container.RegisterPerRequest(service, key, service);
                obj = container.GetInstance(service, key);
            }

            return obj;
        }
        #endregion

        #region GetAllInstances
        protected override IEnumerable<object> GetAllInstances(Type service)
        {
            return container.GetAllInstances(service);
        }
        #endregion

        #region BuildUp
        protected override void BuildUp(object instance)
        {
            container.BuildUp(instance);
        }
        #endregion

        #region PrepareViewFirst
        protected override void PrepareViewFirst(Frame rootFrame)
        {
            container.RegisterNavigationService(rootFrame);
        }
        #endregion
    }
}
